//
//  main.m
//  C06_结构体
//
//  Created by dllo on 15/11/24.
//  Copyright © 2015年 dllo. All rights reserved.
//

#import <Foundation/Foundation.h>

struct ArrStruct {
    int array[20];
};
typedef struct ArrStruct ArrStruct;


/** typedef 将结构体类型重定义 */
struct ClassRoom {
    float area;
    int floor;
};
typedef struct ClassRoom ClaassRoom;  //第一种写法



typedef struct Computer {
    float cpu;
    char color[20];
} Computer;  /**< 此处的Computer为新的类型名 */     //第二种写法
typedef struct Computer Computer;







/** 第一种结构体定义写法,通常使用这种 */
struct Student {
    char name[20];      /**< 姓名 */
    int age;            /**< 年龄 */
    int number;         /**< 学号 */
    float weight;       /**< 体重 */
};
struct Teacher {
    int age;
    char name[10];
    float weight;
    ClaassRoom classroom;      /**< 结构体嵌套 */
};
typedef struct Teacher Teacher;

/** 第二种结构体变量的写法 */
struct Driver {
    char name[20];
    char sex;
} dri1, dri2;  /**< 此处的dir1, dir2是一个变量(两个变量) */
typedef struct Driver Driver;

/** 第三种结构体变量的写法,此写法称为匿名结构体 */
struct {
    char name[20];
    int age;
} englishTeacher;   /**< englishTeacher为变量名 */


int main(int argc, const char * argv[]) {

#pragma mark - 知识点1 结构体定义
    
    /** 结构体语法
     *
     * struct 结构体名{
     
        类型 成员名;
        类型 成员名;
        ...
     
     };
     */

    
    /** 定义一个结构体变量
     * 说明
     * 其中 struct Student 相当于 int
     *      stu1 相当于 a
     */
    
    /** 通常,结构体在函数的外面定义.详见main函数上面代码部分 */
    
#if 0
    struct Student stu1 = {"Tom", 22, 17, 63.2};
    struct Student stu2 = {"kobe", 37, 1, 90.5};
    struct Student stu3 = {"James", 32, 2, 90.8};
    
    struct Teacher tea1 = {"wangQiang", 36, 70};
    
    
    // dri1 = {"Tom", 'm'};   注意:结构体变量不能这样整体赋值,只能成员变量单独赋值
    //  dri1.name = "wangQiang";   注意:成员变量如果是字符串,不能直接赋值,需要通过strcpy函数
    strcpy(dri1.name, "wangQiang");
    dri1.sex = 'm';
    
    strcpy(englishTeacher.name, "wangQiang");
    englishTeacher.age = 80;
#endif
   
#pragma mark - 知识点2 用typedef定义结构体类型
    
    /** typrdef 的目的: 为了简化类型
     * 例如:struct Teacher 简化成 Teacher
     *     int[] 简化为 Array
     * typedef适用于任何类型,即可以讲任何类型重定义
     */
    
    /** 详见 main 函数上面代码部分 */
#if 0
    ClaassRoom class1 = {100, 3};
    
    Computer pc1 = {1.5, "white"};
#endif
    
    
 
#pragma mark - 知识点3 结构体变量赋值
#if 0
    Teacher tea1 = {"wangQiang", 80, 170};
    Teacher tea2 = tea1;       /**< 结构体变量可以直接赋值 */
    printf("name = %s\n", tea2.name);
    printf("age = %d\n", tea2.age);
    printf("weight = %.2f\n", tea2.weight);
    
    
    /** 数组变量不能直接赋值 */
    
    int array1[5] = {1, 2, 3, 4, 5};
    int array2[5] = {};
 //   array2 = array1;    /**< 数组变量不能直接赋值 */
    
    /** 小技巧:把数组作为结构体的一个成员,通过结构体变量直接赋值,实现数组赋值 */
    
    ArrStruct struct1 = {{1, 2, 3, 4}};
    
    ArrStruct struct2 = struct1;
    
    for (int i = 0; i < 4; i++) {
        printf("%d ", struct2.array[i]);
    }
#endif
#pragma mark - 知识点4 结构体内存的占用
#if 0
    Teacher tea3 = {80, "wangQiang", 170};
    
    printf("size: %lu\n", sizeof(tea3));
    
#endif
 
#pragma mark - 知识点5 结构体嵌套
    
    /** 详见main函数上面的结构体定义部分 */
    
#pragma mark - 知识点6 结构体数组
    
    /** 
     * 结构体数组,就是数组中的元素类型为结构体
     * 注意:一个数组中的结构体类型要相同
     */
    
    Driver driver1 = {"wangQiang", 'm'};
    Driver driver2 = {"wangYan", 'w'};
    
    Computer computer1 = {3.5, "white"};
    Computer computer2 = {3.2, "black"};
    
    /** 定义一个结构体数组 */
    /** 结构体数组中的结构体类型必须相同 */
//  Driver arrDriver[5] = {driver1, driver2, computer1, computer2};
    
    
    
    
    
    
    

    
    
    
    
    
    
    
    
    
    

    return 0;
}
